package edu.study.ops.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import edu.study.common.util.cache.Cache;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.AppsV1Api;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Deployment;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.openapi.models.V1Service;
import io.kubernetes.client.openapi.models.V1Status;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import io.kubernetes.client.util.Yaml;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class K8sService {
	
	private CoreV1Api coreV1Api;
	
	private AppsV1Api appsV1Api;
	
	@Autowired
    private Cache cache;

	@PostConstruct
	void init() {
		String config = "/template/config";
		InputStream inputStream = this.getClass().getResourceAsStream(config);
		ApiClient apiClient = null;
		try {
			apiClient = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new InputStreamReader(inputStream))).build();
		} catch (IOException e) {
			log.error("K8sService.init(), 配置文件出错,连接不上!");
		}
		Configuration.setDefaultApiClient(apiClient);
		coreV1Api = new CoreV1Api(apiClient);
		appsV1Api = new AppsV1Api(apiClient);
	}

	public V1PodList listPodForAllNamespaces() {
		V1PodList v1PodList = null;
		try {
			v1PodList = coreV1Api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);
			if (v1PodList != null) {
				for (V1Pod item : v1PodList.getItems()) {
					log.info("K8sService.listPodForAllNamespaces, podName={}", item.getMetadata().getName());
				}
			}
		} catch (ApiException e) {
			log.error("K8sService.listPodForAllNamespaces(), 连接或查询出错!", e);
		}
		return v1PodList;
	}
	
	
	/**
     * 加载template下面的yaml配置文件
     */
    public Object loadYaml(String fileName) {
		InputStream inputStream = this.getClass().getResourceAsStream("/template/"+fileName);
        try {
			return Yaml.load(new InputStreamReader(inputStream));
		} catch (Exception e) {
			log.error("K8sService.loadYaml(), 加载template下面的yaml配置文件出错!", e);
		}
        return null;
    }
    
    /**
     * 创建
     */
    public void createFromYaml(String fileName, String nameSpace, String type) throws Exception {
    	Object object = loadYaml(fileName);
    	if("deployment".equals(type)) {
    		V1Deployment body = (V1Deployment) object;
    		body.getMetadata().setName(cache.generateStr("deploymentNo_", 1, null));
    		appsV1Api.createNamespacedDeployment(nameSpace, body, null, null, null);
    	} else if("service".equals(type)) {
    		V1Service body = (V1Service) object;
    		body.getMetadata().setName(cache.generateStr("serviceNo_", 1, null));
    		coreV1Api.createNamespacedService(nameSpace, body, null, null, null);
    	} else {
    		//
    	}
    }
    
    /**
     * 创建deployment
     */
    public V1Deployment createDeployment(String nameSpace, V1Deployment body) throws Exception {
    	return appsV1Api.createNamespacedDeployment(nameSpace, body, null, null, null);
    }

    /**
     * 刪除namespace
     */
    public V1Status deleteDeployment(String nameSpace, String deployeName) throws Exception {
    	return appsV1Api.deleteNamespacedDeployment(deployeName, nameSpace, null, null, null, null, null, null);
    }

    /**
     * 创建service
     */
    public V1Service createService(String nameSpace, V1Service body) throws Exception {
    	return coreV1Api.createNamespacedService(nameSpace, body, null, null, null);
    }
    
    /**
     * 删除service
     */
    public V1Status deleteService(String nameSpace, String serviceName) throws Exception {
    	return coreV1Api.deleteNamespacedService(serviceName, nameSpace, null, null, null, null, null, null);
    }
}